package com.winit.issue.repository;

import com.winit.common.util.DateGenerator;
import com.winit.issue.model.Issue;
import org.springframework.stereotype.Repository;
import org.springframework.util.StringUtils;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.criteria.*;
import javax.transaction.Transactional;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.*;

@Repository
public class IssueRepositoryExt {
    @PersistenceContext
    private EntityManager em;

    @Transactional
    public void updateByPropertyNotNull(Issue issue) {
//        Field[] fields=ProductLine.class.getDeclaredFields();
        CriteriaBuilder cb = em.getCriteriaBuilder();

        CriteriaUpdate<Issue> op = cb.createCriteriaUpdate(Issue.class);
        Root<Issue> root = op.from(Issue.class);
//        if (null != issue.getCreateTime()) {
//            op.set("createTime", issue.getCreateTime());
//        }
        if (null != issue.getAction()) {
            op.set("action", issue.getAction());
        }
        if (null != issue.getBrdId()) {
            op.set("brdId", issue.getBrdId());
        }
        if (null != issue.getDescription()) {
            op.set("description", issue.getDescription());
        }
        if (null != issue.getNumber()) {
            op.set("number", issue.getNumber());
        }
        if (null != issue.getStatus()) {
            op.set("status", issue.getStatus());
        }
        if (null != issue.getToAccount()) {
            op.set("toAccount", issue.getToAccount());
        }
        if (null != issue.getType()) {
            op.set("type", issue.getType());
        }
        if (null != issue.getUser()) {
            op.set("user", issue.getUser());
        }
        if (null != issue.getGroupTag()) {
            op.set("groupTag", issue.getGroupTag());
        }
        if (null != issue.getContent()) {
            op.set("content", issue.getContent());
        }

        op.set("updateTime", new Date());

        op.where(cb.equal(root.get("id"), issue.getId()));

        em.createQuery(op).executeUpdate();
    }

    public List<Issue> searchByConditition(Issue issue, String statusExt){
        return this.searchByConditition(issue, statusExt, null,  false,null);
    }

//    @Transactional
    public List<Issue> searchByConditition(Issue issue, String statusExt, String keyword,  boolean orderByCreateTimeDesc,Long startDate) {

//        Field[] fields=ProductLine.class.getDeclaredFields();
        CriteriaBuilder cb = em.getCriteriaBuilder();

        CriteriaQuery<Issue> query = cb.createQuery(Issue.class);
        Root<Issue> root = query.from(Issue.class);
        List<Predicate> predicates = new ArrayList();
        if (null != issue.getId()) {
            predicates.add(cb.equal(root.get("id"), issue.getId()));
        }
        if (null != issue.getCreateTime()) {
            predicates.add(cb.equal(root.get("createTime"), issue.getCreateTime()));
        }
        if (null != issue.getAction()) {
            predicates.add(cb.equal(root.get("action"), issue.getAction()));
        }
        if (null != issue.getBrdId()) {
            predicates.add(cb.equal(root.get("brdId"), issue.getBrdId()));
        }
        if (null != issue.getCreatorAccount()) {
            predicates.add(cb.equal(root.get("creatorAccount"), issue.getCreatorAccount()));
        }
        if (null != issue.getDescription()) {
            predicates.add(cb.equal(root.get("description"), issue.getDescription()));
        }
        if (null != issue.getNumber()) {
            predicates.add(cb.equal(root.get("number"), issue.getNumber()));
        }
        if (null != issue.getStatus()) {
            predicates.add(cb.equal(root.get("status"), issue.getStatus()));
        }
        if (null != statusExt) {
            predicates.add(cb.notEqual(root.get("status"), statusExt));
        }
        if (null != issue.getToAccount()) {
            predicates.add(cb.equal(root.get("toAccount"), issue.getToAccount()));
        }
        if (null != issue.getType()) {
            predicates.add(cb.equal(root.get("type"), issue.getType()));
        }
        if (null != issue.getUser()) {
            predicates.add(cb.equal(root.get("user"), issue.getUser()));
        }
        if (null != issue.getCreatorName()) {
            predicates.add(cb.equal(root.get("creatorName"), issue.getCreatorName()));
        }

        if (!StringUtils.isEmpty(keyword)){
            List<Predicate> keywordPredicates = new ArrayList<>();
            String keyword_ = "%" + keyword + "%";
//            cb.like(root.get("action"), keyword)
            keywordPredicates.add(cb.like(root.get("action").as(String.class), keyword_));
            keywordPredicates.add(cb.like(root.get("description").as(String.class), keyword_));
            keywordPredicates.add(cb.like(root.get("groupTag").as(String.class), keyword_));
            keywordPredicates.add(cb.like(root.get("content").as(String.class), keyword_));
            keywordPredicates.add(cb.equal(root.get("number"), keyword));
            predicates.add(cb.or(keywordPredicates.toArray(new Predicate[keywordPredicates.size()])));
        }
        if(null != startDate){
            //大于或等于传入时间
            predicates.add(cb.greaterThanOrEqualTo(root.get("createTime").as(String.class), DateGenerator.getYYYY_MM_DD(startDate)));
        }
        query.where(predicates.toArray(new Predicate[0]));
        if (orderByCreateTimeDesc){
            query.orderBy(cb.desc(root.get("createTime")));
        }
        return em.createQuery(query).getResultList();
    }


}
